﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using myTunes.BO;
using System.Collections.ObjectModel;
using System.ComponentModel;
using myTunes.API;
using iTunesLib;
using System.Windows.Threading;
using System.Diagnostics;
using myTunes.Commands;
using myBoard.Framework;

namespace myTunes
{
    public class iTunesPlayer : INotifyPropertyChanged
    {
        internal iTunesAPI _iTunesApi;
        private bool _isInitialized;
        private ObservableCollection<PlaylistViewModel> _playlists;
        public delegate void CurrentTrackChangedHandler(TrackViewModel newTrack);
        public event CurrentTrackChangedHandler CurrentTrackChanged;
        public PlaylistViewModel _currentPlaylist;
        private ShowHideITunesCommand _showHideITunesCmd;

        public bool IsITunesVisible
        {
            get 
            {
                System.Diagnostics.Process[] procs = System.Diagnostics.Process.GetProcessesByName("itunes");
                foreach (System.Diagnostics.Process proc in procs)
                {
                    if (proc.MainWindowTitle == "iTunes")
                    {
                        return User32.IsWindowVisible(proc.MainWindowHandle);
                        
                    }
                }
                return false;
            }
        }

        public ShowHideITunesCommand ShowHideITunesCmd
        {
            get { return _showHideITunesCmd; }
        }

        public PlaylistViewModel CurrentPlaylist 
        {
            get
            {
                return _currentPlaylist;
            }
            set
            {
                _currentPlaylist = value;
                RaisePropertyChanged("CurrentPlaylist");
                _currentPlaylist.PlayFirstTrack();
            }
        }

        public bool IsInitialized
        {
            get { return _isInitialized; }
        }

        public ITPlayerState PlayerState
        {
            get 
            {
                return _iTunesApi.PlayerState;
            }
        }
        
        public int PlayerPosition
        {
            get
            {
                return _iTunesApi.PlayerPosition;
            }
            set
            {
                _iTunesApi.PlayerPosition = value;
            }
        }

        public int Volume
        {
            get
            {
                return _iTunesApi.Volume;
            }
            set
            {
                _iTunesApi.Volume = value;
            }
        }

        public bool IsMute
        {
            get
            {
                return _iTunesApi.Mute;
            }
        }

        public ObservableCollection<PlaylistViewModel> Playlists
        {
            get { return _playlists; }
        }

        DispatcherTimer _currentTrackInfoUpdater;

        public iTunesPlayer()
        {
            _playlists = new ObservableCollection<PlaylistViewModel>();
            _showHideITunesCmd = new ShowHideITunesCommand(this);
        }

        public void InitPlayer()
        {            
            _iTunesApi = new iTunesAPI();
            _iTunesApi.ItunesInitilized += new iTunesAPI.ItunesInitilizedHandler(ITunesApi_ItunesInitilized);
            _iTunesApi.NewTrackPlayed += new iTunesAPI.NewTrackPlayedHandler(ITunesApi_NewTrackPlayed);
            _iTunesApi.InitializeItunesAsync(false);            
        }

        void CurrentTrackInfoUpdater_Tick(object sender, EventArgs e)
        {
            if (CurrentPlaylist!=null && CurrentPlaylist.CurrentTrack!=null && PlayerState == ITPlayerState.ITPlayerStatePlaying)
                CurrentPlaylist.CurrentTrack.RaisePropertiesChanged();
        }

        void ITunesApi_NewTrackPlayed(IITTrack track)
        {
            UpdateCurrentPlaylist();
            UpdateCurrentTrack(track);
        }

        void ITunesApi_ItunesInitilized(iTunesLib.iTunesAppClass iTunes)
        {
            if (iTunes == null)
            {
                ExceptionsManager.LogException("myTunes","Failed to initialize myTunes",
                    new Exception("iTunes was not detected. Please install iTunes before using myTunes."),
                    EventLogEntryType.Error, true);
                return;
            }
            RefreshPlaylists();
            UpdateCurrentPlaylist();
            IITTrack track = _iTunesApi.GetCurrentTrack();
            UpdateCurrentTrack(track);
            _currentTrackInfoUpdater = new DispatcherTimer();
            _currentTrackInfoUpdater.Tick += new EventHandler(CurrentTrackInfoUpdater_Tick);
            _currentTrackInfoUpdater.Interval = new TimeSpan(0, 0, 1);
            _currentTrackInfoUpdater.Start();
            _isInitialized = true;
        }

        private void UpdateCurrentTrack(IITTrack track)
        {
            if (track == null)
            {
                CurrentPlaylist.CurrentTrack = CurrentPlaylist.TracksViewModel[0];

                if (CurrentTrackChanged != null)
                    CurrentTrackChanged(CurrentPlaylist.CurrentTrack);
                return;
            }
            
            foreach (TrackViewModel tvm in CurrentPlaylist.TracksViewModel)
            {
                if (tvm.TrackID == track.trackID)
                {
                    CurrentPlaylist.CurrentTrack = tvm;
                    break;
                }
            }

            if (CurrentPlaylist.CurrentTrack == null)
                CurrentPlaylist.CurrentTrack = CurrentPlaylist.TracksViewModel[0];

            if (CurrentTrackChanged != null)
                CurrentTrackChanged(CurrentPlaylist.CurrentTrack);
        }

        private void RefreshPlaylists()
        {
            List<IITPlaylist> pls = _iTunesApi.GetAllPlaylists();
            foreach (IITPlaylist pl in pls)
            {
                if(pl.Kind.ToString()!="ITPlaylistKindLibrary")
                    _playlists.Add(new PlaylistViewModel(pl,this));
            }
            RaisePropertyChanged("Playlists");
        }

        private void UpdateCurrentPlaylist()
        {
            if (_iTunesApi.CurrentPlaylist != null)
            {
                foreach (PlaylistViewModel pvm in _playlists)
                {
                    if (_iTunesApi.CurrentPlaylist.playlistID == pvm.PlaylistID)
                    {
                        _currentPlaylist = pvm;
                        break;
                    }
                }
            }
            if (_currentPlaylist == null)
                _currentPlaylist = _playlists[0];
            RaisePropertyChanged("CurrentPlaylist");
        }

        private void RaisePropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion
    }
}
